<!--
 * @Author: vera_min vera_min@163.com
 * @Date: 2024-12-17 21:51:45
 * @LastEditors: vera_min vera_min@163.com
 * @LastEditTime: 2025-08-22 03:41:54
 * @FilePath: /mail-project/src/components/Common/OneDialog.vue
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
-->
<template>
  <div>
    <!-- 遮罩层 -->
    <div class="dialog-overlay" @touchstart.prevent @touchmove.prevent @touchend.prevent @wheel.prevent @scroll.prevent></div>
    <div ref="boxRef" v-draggable class="box" :class="maximized ? 'max' : ''">
      <div id="form-content" class="box-header">
        <div class="titles">
          <slot name="titles" />
        </div>
      </div>
      <div class="box-content">
        <slot name="content" />
      </div>
    </div>
  </div>
</template>

<script lang="ts" setup>
import { onMounted, ref, onUnmounted, nextTick } from 'vue';

// 定义父组件传过来的值
const props = defineProps({
	// 最大
	maximized: {
		type: Boolean,
		default: () => false,
	},
});

const emit = defineEmits(['close', 'click-outside']);
const boxRef = ref();

// 处理点击外部
const handleClickOutside = (event: any) => {
  // 忽略Select下拉菜单和弹出框的点击
  const ignoreSelectors = [
    '.el-select-dropdown', 
    '.el-popper', 
    '.el-picker__popper',
    '.el-autocomplete-suggestion',
    '.el-dropdown-menu',
    '.contextMenu'
  ];
  
  // 检查点击元素是否匹配忽略选择器
  const shouldIgnore = ignoreSelectors.some(selector => {
    return event.target.closest(selector) !== null;
  });
  
  // 如果点击的是需要忽略的元素，则不触发外部点击
  if (shouldIgnore) {
    return;
  }
  
  // 正常检测点击是否在对话框外部
  if (boxRef.value && !boxRef.value.contains(event.target)) {
    emit('click-outside');
  }
};

// 调整对话框位置到屏幕中心
const centerDialog = () => {
  if (!boxRef.value || props.maximized) return;
  
  nextTick(() => {
    setTimeout(() => {
      try {
        const boxWidth = boxRef.value.offsetWidth;
        const boxHeight = boxRef.value.offsetHeight;
        
        const left = Math.max(0, (window.innerWidth - boxWidth) / 2);
        const top = Math.max(0, window.innerHeight / 3 - boxHeight / 3);
        
        boxRef.value.style.left = `${left}px`;
        boxRef.value.style.top = `${top}px`;
      } catch (e) {
        console.error('Error centering dialog:', e);
      }
    }, 10);
  });
};

onMounted(() => {
  // 初始定位
  centerDialog();
  
  // 禁用body滚动
  document.body.style.overflow = 'hidden';
  
  // 添加事件监听
  window.addEventListener('resize', centerDialog);
  document.addEventListener('mousedown', handleClickOutside);
});

onUnmounted(() => {
  // 恢复body滚动
  document.body.style.overflow = '';

  
  // 移除事件监听
  window.removeEventListener('resize', centerDialog);
  document.removeEventListener('mousedown', handleClickOutside);
});
</script>

<style lang="scss" scoped>
.box {
  position: fixed;
  display: flex;
  flex-direction: column;
  width: 910px;
  min-width: 800px;
  min-height: 400px;
  background: #F5F6F7;
  border: 1px solid #B7B7B7;
  overflow: hidden;
  border-radius: 10px;
  box-shadow: 0px 0px 6px 0px rgba(0,0,0,0.2);
  z-index: 2000;

  &.max {
    left: 0 !important;
    top: 0 !important;
    width: 100vw;
    height: 100vh;
    position: fixed !important;
    .box-header {
      user-select: none;
    }
  }

  &-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    height: 44px;
    padding: 0 13px;
    font-size: 13px;
    font-weight: 300;
    padding-top: 5px;
    cursor: move;

    .titles {
      display: flex;
      align-items: center;
      color: #353535;
      font-weight: 500;
      font-size: 14px;
    }

    .buttons {
      display: flex;
      align-items: center;
      color: #adc6de;

      & > i {
        &:hover {
          color: #fff;
        }
      }
    }
  }

  &-content {
    display: flex;
    flex: 1;
    flex-direction: column;
    height: calc(100% - 24px);
  }
}

.dialog-overlay {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0);
  z-index: 999;
}
</style>
